# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np

import gc
import datetime

def get_train_data(srcTrainDataPath, nrows=None, feaList=None):
	#读取训练集
	df = pd.read_csv(srcTrainDataPath, nrows=nrows)
	#处理注册时间，转化为datetime类型
	df.register_time = df.register_time.apply(pd.to_datetime, format='%Y-%m-%d %H:%M:%S')
	#获得注册信息（year, month, day, hour, weekday）
	df['year'] = df.register_time.apply(lambda x: x.year)
	df['month'] = df.register_time.apply(lambda x: x.month)
	df['day'] = df.register_time.apply(lambda x: x.day)
	df['hour'] = df.register_time.apply(lambda x: x.hour)
	df['weekday'] = df.register_time.apply(lambda x: x.weekday())

	oldFeaList = [
	#  'user_id',
	#  'register_time',
	 'wood_add_value',
	 'wood_reduce_value',
	 'stone_add_value',
	 'stone_reduce_value',
	 'ivory_add_value',
	 'ivory_reduce_value',
	 'meat_add_value',
	 'meat_reduce_value',
	 'magic_add_value',
	 'magic_reduce_value',
	 'infantry_add_value',
	 'infantry_reduce_value',
	 'cavalry_add_value',
	 'cavalry_reduce_value',
	 'shaman_add_value',
	 'shaman_reduce_value',
	 'wound_infantry_add_value',
	 'wound_infantry_reduce_value',
	 'wound_cavalry_add_value',
	 'wound_cavalry_reduce_value',
	 'wound_shaman_add_value',
	 'wound_shaman_reduce_value',
	 'general_acceleration_add_value',
	 'general_acceleration_reduce_value',
	 'building_acceleration_add_value',
	 'building_acceleration_reduce_value',
	 'reaserch_acceleration_add_value',
	 'reaserch_acceleration_reduce_value',
	 'training_acceleration_add_value',
	 'training_acceleration_reduce_value',
	 'treatment_acceleraion_add_value',
	 'treatment_acceleration_reduce_value',
	 'bd_training_hut_level',
	 'bd_healing_lodge_level',
	 'bd_stronghold_level',
	 'bd_outpost_portal_level',
	 'bd_barrack_level',
	 'bd_healing_spring_level',
	 'bd_dolmen_level',
	 'bd_guest_cavern_level',
	 'bd_warehouse_level',
	 'bd_watchtower_level',
	 'bd_magic_coin_tree_level',
	 'bd_hall_of_war_level',
	 'bd_market_level',
	 'bd_hero_gacha_level',
	 'bd_hero_strengthen_level',
	 'bd_hero_pve_level',
	 'sr_scout_level',
	 'sr_training_speed_level',
	 'sr_infantry_tier_2_level',
	 'sr_cavalry_tier_2_level',
	 'sr_shaman_tier_2_level',
	 'sr_infantry_atk_level',
	 'sr_cavalry_atk_level',
	 'sr_shaman_atk_level',
	 'sr_infantry_tier_3_level',
	 'sr_cavalry_tier_3_level',
	 'sr_shaman_tier_3_level',
	 'sr_troop_defense_level',
	 'sr_infantry_def_level',
	 'sr_cavalry_def_level',
	 'sr_shaman_def_level',
	 'sr_infantry_hp_level',
	 'sr_cavalry_hp_level',
	 'sr_shaman_hp_level',
	 'sr_infantry_tier_4_level',
	 'sr_cavalry_tier_4_level',
	 'sr_shaman_tier_4_level',
	 'sr_troop_attack_level',
	 'sr_construction_speed_level',
	 'sr_hide_storage_level',
	 'sr_troop_consumption_level',
	 'sr_rss_a_prod_levell',
	 'sr_rss_b_prod_level',
	 'sr_rss_c_prod_level',
	 'sr_rss_d_prod_level',
	 'sr_rss_a_gather_level',
	 'sr_rss_b_gather_level',
	 'sr_rss_c_gather_level',
	 'sr_rss_d_gather_level',
	 'sr_troop_load_level',
	 'sr_rss_e_gather_level',
	 'sr_rss_e_prod_level',
	 'sr_outpost_durability_level',
	 'sr_outpost_tier_2_level',
	 'sr_healing_space_level',
	 'sr_gathering_hunter_buff_level',
	 'sr_healing_speed_level',
	 'sr_outpost_tier_3_level',
	 'sr_alliance_march_speed_level',
	 'sr_pvp_march_speed_level',
	 'sr_gathering_march_speed_level',
	 'sr_outpost_tier_4_level',
	 'sr_guest_troop_capacity_level',
	 'sr_march_size_level',
	 'sr_rss_help_bonus_level',
	 'pvp_battle_count',
	 'pvp_lanch_count',
	 'pvp_win_count',
	 'pve_battle_count',
	 'pve_lanch_count',
	 'pve_win_count',
	 'avg_online_minutes',
	 'pay_price',
	 'pay_count',
	#  'prediction_pay_price',
	#  'year',
	#  'month',
	#  'day',
	#  'hour',
	#  'weekday'
	]


	newFeaList = [
	    #各种材料使用情况
	    'wood_usage',
	    'stone_usage',
	    'ivory_usage',
	    'meat_usage',
	    'magic_usage',
	    'infantry_usage',
	    'cavalry_usage',
	    'shaman_usage',
	    
	    #各种材料使用情况分布
	    'usage_max',
	    'usage_min',
	    'usage_mean',
	    'usage_std',
	    'usage_gap',
	    'usage_cv',

	    #恢复/消耗情况
	    'wound_infantry_renew',
	    'wound_cavalry_renew',
	    'wound_shaman_renew',
	    
	    #恢复/消耗分布
	    'renew_max',
	    'renew_std',
	    
	    #加速使用情况
	    'general_acceleration_acc_usage',
	    'building_acceleration_acc_usage',
	    'reaserch_acceleration_acc_usage',
	    'training_acceleration_acc_usage',
	    'treatment_acceleration_acc_usage',
	    
	    #加速使用情况分布
	    'acc_usage_max',
	    'acc_usage_min',
	    'acc_usage_mean',
	    'acc_usage_std',
	    'acc_usage_gap',
	    'acc_usage_cv',
	    
	    #建筑等级发展分布
	    'bd_level_max',
	    'bd_level_min',
	    'bd_level_mean',
	    'bd_level_std',
	    'bd_level_gap',
	    'bd_level_cv',
	    
	    #科研等级发展分布
	    'sr_level_max',
	    'sr_level_min',
	    'sr_level_mean',
	    'sr_level_std',
	    'sr_level_gap',
	    'sr_level_cv',
	    
	    #等级发展均衡性
	    'max_level_balance',
	    'mean_level_balance',
	    
	    #PVP/PVE主动发起比例
	    'pvp_battle_lanch_ratio',
	    'pve_battle_lanch_ratio',
	    
	    #PVP/PVE获胜比例
	    'pvp_battle_win_ratio',
	    'pve_battle_win_ratio',
	    
	    #主动发起的PVP/PVE获胜比例
	    'pvp_battle_lanch_win_ratio',
	    'pve_battle_lanch_win_ratio',
	    
	    #被动发起的PVP/PVE获胜比例
	    'pvp_battle_no_lanch_win_ratio',
	    'pve_battle_no_lanch_win_ratio'
	]


	#特征工程
	#各类物品的使用率，以usage结尾
	df['wood_usage'] = df['wood_reduce_value'] / (df['wood_add_value'] + 1)
	df['stone_usage'] = df['stone_reduce_value'] / (df['stone_add_value'] + 1)
	df['ivory_usage'] = df['ivory_reduce_value'] / (df['ivory_add_value'] + 1)
	df['meat_usage'] = df['meat_reduce_value'] / (df['meat_add_value'] + 1)
	df['magic_usage'] = df['magic_reduce_value'] / (df['magic_add_value'] + 1)
	df['infantry_usage'] = df['infantry_reduce_value'] / (df['infantry_add_value'] + 1)
	df['cavalry_usage'] = df['cavalry_reduce_value'] / (df['cavalry_add_value'] + 1)
	df['shaman_usage'] = df['shaman_reduce_value'] / (df['shaman_add_value'] + 1)

	#各类物品使用率均值、最大值、最小值
	df['usage_max'] = np.max(df[['wood_usage',
	    'stone_usage',
	    'ivory_usage',
	    'meat_usage',
	    'magic_usage',
	    'infantry_usage',
	    'cavalry_usage',
	    'shaman_usage']], axis=1)
	df['usage_mean'] = np.mean(df[['wood_usage',
	    'stone_usage',
	    'ivory_usage',
	    'meat_usage',
	    'magic_usage',
	    'infantry_usage',
	    'cavalry_usage',
	    'shaman_usage']], axis=1)
	df['usage_std'] = np.std(df[['wood_usage',
	    'stone_usage',
	    'ivory_usage',
	    'meat_usage',
	    'magic_usage',
	    'infantry_usage',
	    'cavalry_usage',
	    'shaman_usage']], axis=1)
	df['usage_min'] = np.min(df[['wood_usage',
	    'stone_usage',
	    'ivory_usage',
	    'meat_usage',
	    'magic_usage',
	    'infantry_usage',
	    'cavalry_usage',
	    'shaman_usage']], axis=1)
	df['usage_gap'] = df['usage_max'] - df['usage_min']
	df['usage_cv'] = df['usage_std'] / (df['usage_mean'] - 1e-5)

	#伤亡恢复情况，以renew结尾
	df['wound_infantry_renew'] = df['wound_infantry_reduce_value'] / (df['wound_infantry_add_value'] + 1)
	df['wound_cavalry_renew'] = df['wound_cavalry_reduce_value'] / (df['wound_cavalry_add_value'] + 1)
	df['wound_shaman_renew'] = df['wound_shaman_reduce_value'] / (df['wound_shaman_add_value'] + 1)

	df['renew_max'] = np.max(df[['wound_infantry_renew',
	    'wound_cavalry_renew',
	    'wound_shaman_renew']], axis=1)
	df['renew_std'] = np.std(df[['wound_infantry_renew',
	    'wound_cavalry_renew',
	    'wound_shaman_renew']], axis=1)

	#加速获取情况，以acc_usage结尾
	df['general_acceleration_acc_usage'] = df['general_acceleration_reduce_value'] / (df['general_acceleration_add_value'] + 1)
	df['building_acceleration_acc_usage'] = df['building_acceleration_reduce_value'] / (df['building_acceleration_add_value'] + 1)
	df['reaserch_acceleration_acc_usage'] = df['reaserch_acceleration_reduce_value'] / (df['reaserch_acceleration_add_value'] + 1)
	df['training_acceleration_acc_usage'] = df['training_acceleration_reduce_value'] / (df['training_acceleration_add_value'] + 1)
	df['treatment_acceleration_acc_usage'] = df['treatment_acceleration_reduce_value'] / (df['treatment_acceleraion_add_value'] + 1)

	df['acc_usage_max'] = np.max(df[['general_acceleration_acc_usage',
	    'building_acceleration_acc_usage',
	    'reaserch_acceleration_acc_usage',
	    'training_acceleration_acc_usage',
	    'treatment_acceleration_acc_usage']], axis=1)
	df['acc_usage_min'] = np.min(df[['general_acceleration_acc_usage',
	    'building_acceleration_acc_usage',
	    'reaserch_acceleration_acc_usage',
	    'training_acceleration_acc_usage',
	    'treatment_acceleration_acc_usage']], axis=1)
	df['acc_usage_mean'] = np.mean(df[['general_acceleration_acc_usage',
	    'building_acceleration_acc_usage',
	    'reaserch_acceleration_acc_usage',
	    'training_acceleration_acc_usage',
	    'treatment_acceleration_acc_usage']], axis=1)
	df['acc_usage_std'] = np.std(df[['general_acceleration_acc_usage',
	    'building_acceleration_acc_usage',
	    'reaserch_acceleration_acc_usage',
	    'training_acceleration_acc_usage',
	    'treatment_acceleration_acc_usage']], axis=1)
	df['acc_usage_gap'] = df['acc_usage_max'] - df['acc_usage_min']
	df['acc_usage_cv'] = df['acc_usage_std'] / (df['acc_usage_mean'] - 1e-5)

	#建筑等级分布情况
	bd_level_fea_list = ['bd_training_hut_level',
	 'bd_healing_lodge_level',
	 'bd_stronghold_level',
	 'bd_outpost_portal_level',
	 'bd_barrack_level',
	 'bd_healing_spring_level',
	 'bd_dolmen_level',
	 'bd_guest_cavern_level',
	 'bd_warehouse_level',
	 'bd_watchtower_level',
	 'bd_magic_coin_tree_level',
	 'bd_hall_of_war_level',
	 'bd_market_level',
	 'bd_hero_gacha_level',
	 'bd_hero_strengthen_level',
	 'bd_hero_pve_level'
	]
	df['bd_level_max'] = np.max(df[bd_level_fea_list], axis=1)
	df['bd_level_min'] = np.min(df[bd_level_fea_list], axis=1)
	df['bd_level_mean'] = np.mean(df[bd_level_fea_list], axis=1)
	df['bd_level_std'] = np.std(df[bd_level_fea_list], axis=1)
	df['bd_level_gap'] = df['bd_level_max'] - df['bd_level_min']
	df['bd_level_cv'] = df['bd_level_std'] / (df['bd_level_mean'] - 1e-2)

	#科研等级分布情况
	sr_level_fea_list = ['sr_scout_level',
	 'sr_training_speed_level',
	 'sr_infantry_tier_2_level',
	 'sr_cavalry_tier_2_level',
	 'sr_shaman_tier_2_level',
	 'sr_infantry_atk_level',
	 'sr_cavalry_atk_level',
	 'sr_shaman_atk_level',
	 'sr_infantry_tier_3_level',
	 'sr_cavalry_tier_3_level',
	 'sr_shaman_tier_3_level',
	 'sr_troop_defense_level',
	 'sr_infantry_def_level',
	 'sr_cavalry_def_level',
	 'sr_shaman_def_level',
	 'sr_infantry_hp_level',
	 'sr_cavalry_hp_level',
	 'sr_shaman_hp_level',
	 'sr_infantry_tier_4_level',
	 'sr_cavalry_tier_4_level',
	 'sr_shaman_tier_4_level',
	 'sr_troop_attack_level',
	 'sr_construction_speed_level',
	 'sr_hide_storage_level',
	 'sr_troop_consumption_level',
	 'sr_rss_a_prod_levell',
	 'sr_rss_b_prod_level',
	 'sr_rss_c_prod_level',
	 'sr_rss_d_prod_level',
	 'sr_rss_a_gather_level',
	 'sr_rss_b_gather_level',
	 'sr_rss_c_gather_level',
	 'sr_rss_d_gather_level',
	 'sr_troop_load_level',
	 'sr_rss_e_gather_level',
	 'sr_rss_e_prod_level',
	 'sr_outpost_durability_level',
	 'sr_outpost_tier_2_level',
	 'sr_healing_space_level',
	 'sr_gathering_hunter_buff_level',
	 'sr_healing_speed_level',
	 'sr_outpost_tier_3_level',
	 'sr_alliance_march_speed_level',
	 'sr_pvp_march_speed_level',
	 'sr_gathering_march_speed_level',
	 'sr_outpost_tier_4_level',
	 'sr_guest_troop_capacity_level',
	 'sr_march_size_level',
	 'sr_rss_help_bonus_level'
	]
	df['sr_level_max'] = np.max(df[sr_level_fea_list], axis=1)
	df['sr_level_min'] = np.min(df[sr_level_fea_list], axis=1)
	df['sr_level_mean'] = np.mean(df[sr_level_fea_list], axis=1)
	df['sr_level_std'] = np.std(df[sr_level_fea_list], axis=1)
	df['sr_level_gap'] = df['sr_level_max'] - df['sr_level_min']
	df['sr_level_cv'] = df['sr_level_std'] / (df['sr_level_mean'] - 1e-2)

	#等级发展均衡性
	df['max_level_balance'] = df['sr_level_max'] / df['bd_level_max']
	df['mean_level_balance'] = df['sr_level_mean'] / df['bd_level_mean']

	#PVP/PVE主动发起比例
	df['pvp_battle_lanch_ratio'] = df['pvp_lanch_count'] / (df['pvp_battle_count'] - 1e-2)
	df['pve_battle_lanch_ratio'] = df['pve_lanch_count'] / (df['pve_battle_count'] - 1e-2)

	#PVP/PVE获胜比例
	df['pvp_battle_win_ratio'] = df['pvp_win_count'] / (df['pvp_battle_count'] - 1e-2)
	df['pve_battle_win_ratio'] = df['pve_win_count'] / (df['pve_battle_count'] - 1e-2)

	#主动发起的PVP/PVE获胜比例
	df['pvp_battle_lanch_win_ratio'] = df['pvp_win_count'] / (df['pvp_lanch_count'] - 1e-2)
	df['pve_battle_lanch_win_ratio'] = df['pve_win_count'] / (df['pve_lanch_count'] - 1e-2)

	#被动发起的PVP/PVE获胜比例
	df['pvp_battle_no_lanch_win_ratio'] = df['pvp_win_count'] / (df['pvp_battle_count'] - df['pvp_lanch_count'] - 1e-2)
	df['pve_battle_no_lanch_win_ratio'] = df['pve_win_count'] / (df['pve_battle_count'] - df['pve_lanch_count'] - 1e-2)

	if feaList is not None:
		df = df[feaList]

	return df

def get_desc_of_all_fea(df, feaList):
	mean_dict = {}
	max_dict = {}
	min_dict = {}
	std_dict = {}

	for fea in feaList:
	    mean_dict[fea] = df[fea].mean()
	    max_dict[fea] = df[fea].max()
	    min_dict[fea] = df[fea].min()
	    std_dict[fea] = df[fea].std()
	return mean_dict, max_dict, min_dict, std_dict

def data_standardization(df, feaList, mean_dict, max_dict, min_dict, std_dict):
	for fea in feaList:
		df[fea] = (df[fea] - mean_dict[fea]) / (std_dict[fea] - 1e-6)

	return df

if __name__ == '__main__':
	runTime = datetime.datetime.now().strftime('%Y%m%d%H%M')

	nrows = 10
	get_new_train = True

	srcTrainDataPath = '../data/tap_fun_train.csv'
	trainDataPath = '../train_data/train_data' + runTime + '.csv'
	doneTrainDataPath = '../train_data/train_data.csv'

	feaList = [
		#  'user_id',
		#  'register_time',
		'wood_add_value',
		'wood_reduce_value',
		'stone_add_value',
		'stone_reduce_value',
		'ivory_add_value',
		'ivory_reduce_value',
		'meat_add_value',
		'meat_reduce_value',
		'magic_add_value',
		'magic_reduce_value',
		'infantry_add_value',
		'infantry_reduce_value',
		'cavalry_add_value',
		'cavalry_reduce_value',
		'shaman_add_value',
		'shaman_reduce_value',
		'wound_infantry_add_value',
		'wound_infantry_reduce_value',
		'wound_cavalry_add_value',
		'wound_cavalry_reduce_value',
		'wound_shaman_add_value',
		'wound_shaman_reduce_value',
		'general_acceleration_add_value',
		'general_acceleration_reduce_value',
		'building_acceleration_add_value',
		'building_acceleration_reduce_value',
		'reaserch_acceleration_add_value',
		'reaserch_acceleration_reduce_value',
		'training_acceleration_add_value',
		'training_acceleration_reduce_value',
		'treatment_acceleraion_add_value',
		'treatment_acceleration_reduce_value',
		'bd_training_hut_level',
		'bd_healing_lodge_level',
		'bd_stronghold_level',
		'bd_outpost_portal_level',
		'bd_barrack_level',
		'bd_healing_spring_level',
		'bd_dolmen_level',
		'bd_guest_cavern_level',
		'bd_warehouse_level',
		'bd_watchtower_level',
		'bd_magic_coin_tree_level',
		'bd_hall_of_war_level',
		'bd_market_level',
		'bd_hero_gacha_level',
		'bd_hero_strengthen_level',
		'bd_hero_pve_level',
		'sr_scout_level',
		'sr_training_speed_level',
		'sr_infantry_tier_2_level',
		'sr_cavalry_tier_2_level',
		'sr_shaman_tier_2_level',
		'sr_infantry_atk_level',
		'sr_cavalry_atk_level',
		'sr_shaman_atk_level',
		'sr_infantry_tier_3_level',
		'sr_cavalry_tier_3_level',
		'sr_shaman_tier_3_level',
		'sr_troop_defense_level',
		'sr_infantry_def_level',
		'sr_cavalry_def_level',
		'sr_shaman_def_level',
		'sr_infantry_hp_level',
		'sr_cavalry_hp_level',
		'sr_shaman_hp_level',
		'sr_infantry_tier_4_level',
		'sr_cavalry_tier_4_level',
		'sr_shaman_tier_4_level',
		'sr_troop_attack_level',
		'sr_construction_speed_level',
		'sr_hide_storage_level',
		'sr_troop_consumption_level',
		'sr_rss_a_prod_levell',
		'sr_rss_b_prod_level',
		'sr_rss_c_prod_level',
		'sr_rss_d_prod_level',
		'sr_rss_a_gather_level',
		'sr_rss_b_gather_level',
		'sr_rss_c_gather_level',
		'sr_rss_d_gather_level',
		'sr_troop_load_level',
		'sr_rss_e_gather_level',
		'sr_rss_e_prod_level',
		'sr_outpost_durability_level',
		'sr_outpost_tier_2_level',
		'sr_healing_space_level',
		'sr_gathering_hunter_buff_level',
		'sr_healing_speed_level',
		'sr_outpost_tier_3_level',
		'sr_alliance_march_speed_level',
		'sr_pvp_march_speed_level',
		'sr_gathering_march_speed_level',
		'sr_outpost_tier_4_level',
		'sr_guest_troop_capacity_level',
		'sr_march_size_level',
		'sr_rss_help_bonus_level',
		'pvp_battle_count',
		'pvp_lanch_count',
		'pvp_win_count',
		'pve_battle_count',
		'pve_lanch_count',
		'pve_win_count',
		'avg_online_minutes',
		'pay_price',
		'pay_count',
		#  'prediction_pay_price',
		'year',
		'month',
		'day',
		'hour',
		'weekday',

		#各种材料使用情况
		'wood_usage',
		'stone_usage',
		'ivory_usage',
		'meat_usage',
		'magic_usage',
		'infantry_usage',
		'cavalry_usage',
		'shaman_usage',

		#各种材料使用情况分布
		'usage_max',
		'usage_min',
		'usage_mean',
		'usage_std',
		'usage_gap',
		'usage_cv',

		#恢复/消耗情况
		'wound_infantry_renew',
		'wound_cavalry_renew',
		'wound_shaman_renew',

		#恢复/消耗分布
		'renew_max',
		'renew_std',

		#加速使用情况
		'general_acceleration_acc_usage',
		'building_acceleration_acc_usage',
		'reaserch_acceleration_acc_usage',
		'training_acceleration_acc_usage',
		'treatment_acceleration_acc_usage',

		#加速使用情况分布
		'acc_usage_max',
		'acc_usage_min',
		'acc_usage_mean',
		'acc_usage_std',
		'acc_usage_gap',
		'acc_usage_cv',

		#建筑等级发展分布
		'bd_level_max',
		'bd_level_min',
		'bd_level_mean',
		'bd_level_std',
		'bd_level_gap',
		'bd_level_cv',

		#科研等级发展分布
		'sr_level_max',
		'sr_level_min',
		'sr_level_mean',
		'sr_level_std',
		'sr_level_gap',
		'sr_level_cv',

		#等级发展均衡性
		'max_level_balance',
		'mean_level_balance',

		#PVP/PVE主动发起比例
		'pvp_battle_lanch_ratio',
		'pve_battle_lanch_ratio',

		#PVP/PVE获胜比例
		'pvp_battle_win_ratio',
		'pve_battle_win_ratio',

		#主动发起的PVP/PVE获胜比例
		'pvp_battle_lanch_win_ratio',
		'pve_battle_lanch_win_ratio',

		#被动发起的PVP/PVE获胜比例
		'pvp_battle_no_lanch_win_ratio',
		'pve_battle_no_lanch_win_ratio'
	]

	#初始化训练数据集
	df = None
	if get_new_train is True:
		df = get_train_data(srcTrainDataPath, nrows=nrows)

		#获取各个特征的统计值
		mean_dict, max_dict, min_dict, std_dict = get_desc_of_all_fea(df, feaList)

		#对数据集进行标准化处理
		df = data_standardization(df, feaList, mean_dict, max_dict, min_dict, std_dict)

		#将训练集存入文件
		df.to_csv(trainDataPath, index=None)
	else:
		df = pd.read_csv(doneTrainDataPath)

	print ('get_train_data ok!', datetime.datetime.now())



